package fr.norsys.mapper.console.web;

import java.util.Collection;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.navigator.menu.MenuRepository;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

import fr.norsys.mapper.console.exception.ConnectionException;
import fr.norsys.mapper.console.exception.PropertyException;
import fr.norsys.mapper.console.model.Connection;
import fr.norsys.mapper.console.model.ConsoleCst;
import fr.norsys.mapper.console.service.ConnectionService;
import fr.norsys.mapper.console.service.MenuService;
import fr.norsys.mapper.console.service.PropertyService;
import fr.norsys.mapper.console.utils.BeanUtils;

/**
 * Struts Action that manages connections
 * 
 * @author jeff
 * @version 0.1
 */
public class ConnectionAction extends BaseAppDispatchAction {
	private static Log log = LogFactory.getLog(ConnectionAction.class);

	private PropertyService propertyService;

	private ConnectionService connectionService;

	private MenuService menuService;

	/**
	 * This method is called for initialization. This method creates an empty
	 * connection bean.
	 */
	public ActionForward init(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		if (log.isDebugEnabled()) {
			log.debug("init method called");
		}
		DynaActionForm connectionForm = (DynaActionForm) form;
		connectionForm
				.set(ConsoleCst.CONNECTION_REQUEST_BEAN, new Connection());
		request.getSession().setAttribute(ConsoleCst.IS_APPLICATION_MODIFIED,
				ConsoleCst.APPLICATION_NOT_MODIFIED);
		refreshMenu(request, "");
		return mapping.findForward(ConsoleCst.CONNECTIONS_PAGE_FORWARD);
	}

	/**
	 * This method is called to save the connection in the session. This method
	 * is used to add a new connection or to modify parameters of the
	 * connection.
	 */
	public ActionForward save(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		if (log.isDebugEnabled()) {
			log.debug("save method called");
		}
		DynaActionForm connectionForm = (DynaActionForm) form;
		Connection connection = (Connection) connectionForm
				.get(ConsoleCst.CONNECTION_REQUEST_BEAN);
		String forward = request.getParameter("forward");
		if (log.isDebugEnabled()) {
			log.debug(connection);
		}
		connectionService.save(connection, (Collection) request.getSession()
				.getAttribute(ConsoleCst.CONNECTIONS_SESSION_BEAN));
		String caller = request.getParameter("caller");
		if (!"connections".equals(caller)) {
			request.getSession().setAttribute(
					ConsoleCst.IS_CONNECTION_MODIFIED,
					ConsoleCst.CONNECTION_MODIFIED);
		}
		refreshMenu(request, connection.getId());
		return mapping.findForward(forward);
	}

	/**
	 * This method is called to delete a connection.
	 */
	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		if (log.isDebugEnabled()) {
			log.debug("delete method called");
		}
		DynaActionForm connectionForm = (DynaActionForm) form;
		Connection connection = (Connection) connectionForm
				.get(ConsoleCst.CONNECTION_REQUEST_BEAN);
		connectionService
				.delete(connection.getId(), (Collection) request.getSession()
						.getAttribute(ConsoleCst.CONNECTIONS_SESSION_BEAN));
		refreshMenu(request, connection.getId());
		blankConnectionBean(form);
		return mapping.findForward(ConsoleCst.CONNECTIONS_PAGE_FORWARD);
	}

	/**
	 * This method edits the connection.
	 */
	public ActionForward edit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		if (log.isDebugEnabled()) {
			log.debug("edit method called");
		}
		String id = request.getParameter("id");
		String forward = request.getParameter("forward");
		DynaActionForm connectionForm = (DynaActionForm) form;
		if (log.isDebugEnabled()) {
			log.debug(id);
		}
		Connection connection = null;
		if (id != null && !"".equals(id)) {
			connection = connectionService.get(id, (Collection) request
					.getSession().getAttribute(
							ConsoleCst.CONNECTIONS_SESSION_BEAN));
			if (connection == null || connection.getUrl() == null) {
				String name = connection.getName();
				Map map;
				map = propertyService.getProperty(connectionService
						.getConnectionsDirPath()
						+ name + ".properties");
				if (log.isDebugEnabled()) {
					log.debug(map);
				}
				BeanUtils.toObject(map, connection);
			}
		}
		request.getSession().setAttribute(ConsoleCst.IS_APPLICATION_MODIFIED,
				ConsoleCst.APPLICATION_NOT_MODIFIED);
		refreshMenu(request, id);
		connectionForm.set(ConsoleCst.CONNECTION_REQUEST_BEAN, connection);
		return mapping.findForward(forward);
	}

	/**
	 * This method refreshs the menu.
	 */
	private void refreshMenu(HttpServletRequest request, String id)  throws Exception {
		MenuRepository oldRepository = (MenuRepository) getServlet()
				.getServletContext().getAttribute(
						MenuRepository.MENU_REPOSITORY_KEY);
		MenuRepository menu = menuService.buildConMenu(oldRepository,
				(Collection) request.getSession().getAttribute(
						ConsoleCst.APPLICATIONS_SESSION_BEAN),
				(Collection) request.getSession().getAttribute(
						ConsoleCst.CONNECTIONS_SESSION_BEAN), (String) request
						.getSession().getAttribute(
								ConsoleCst.IS_CONNECTION_MODIFIED), id);
		request.getSession().setAttribute("nodeList", menu);
	}

	private void blankConnectionBean(ActionForm form) {
		((DynaActionForm) form).set("connection", new Connection());
	}

	public ConnectionService getConnectionService() {
		return connectionService;
	}

	public void setConnectionService(ConnectionService connectionService) {
		this.connectionService = connectionService;
	}

	public PropertyService getPropertyService() {
		return propertyService;
	}

	public void setPropertyService(PropertyService propertyService) {
		this.propertyService = propertyService;
	}

	public MenuService getMenuService() {
		return menuService;
	}

	public void setMenuService(MenuService menuService) {
		this.menuService = menuService;
	}
}